package beastick.utility;

//Copyright 2008 Tofig Kareemov, estereos@gmail.com
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;

import beastick.security.generic.SecureHash;
import beastick.security.generic.SecureRandom;

public class CFileTools extends CPrint
{
 public final int I_FILE_OVERRIDE_ALWAYS    = 0;

 public final int I_FILE_OVERRIDE_NEVER     = 1;

 public final int I_FILE_OVERRIDE_ASK       = 2;

 public final int I_FILE_OVERRIDE_DIFFERENT = 3;

 public final int I_FILE_OVERRIDE_NEWER     = 4;

 private CMatcher oMatcher                  = new CMatcher();

 public String FindFile(String sFileName)
 {
  String sResult = sFileName;
  if (!IsValuable(sResult))
  {
   return "";
  }
  if (!FileExists(sResult))
  {
   sResult = System.getProperty("tofig_home", "./") + "/" + sFileName;
  }
  if (!FileExists(sResult))
  {
   sResult = System.getProperty("user.home", "./") + "/tofig/" + sFileName;
  }
  if (!FileExists(sResult))
  {
   sResult = "";
  }
  return sResult;
 }

 public String FindResource(String sFileName)
 {
  String sResult = "";
  if (!IsValuable(sFileName))
  {
   return "";
  }
  try
  {
   URL url = Thread.currentThread().getContextClassLoader().getResource(
     sFileName);
   if (url != null)
    sResult = url.getFile();
  } catch (Throwable t)
  {
  }
  return sResult;
 }

 public String FindFileFullName(String sFileName)
 {
  return SystemFileFullName(FindFile(sFileName));
 }

 public String SystemFileFullName(String sFileName)
 {
  String sResult = "";
  File oFile = new File(sFileName);
  if (oFile.exists())
  {
   try
   {
    sResult = oFile.getCanonicalPath();
   } catch (Throwable T)
   {
   }
  }
  sResult = sResult.replace('\\', '/');
  return sResult;
 }

 public void SetPrint(String isPrintPattern, int iiPrintType)
 {
  iPrintType = iiPrintType;
  sPrintPattern = isPrintPattern;
 }

 public boolean DeleteFile(String sFileName)
 {
  boolean bResult = true;
  File oFile = null;
  if (IsValuable(sFileName))
  {
   oFile = new File(sFileName);
   if (oFile.exists())
   {
    oFile.delete();
   }
  }
  return bResult;
 };

 public boolean MoveFile(String sSourceFileName, String sTargetFileName)
 {
  boolean bResult = false;
  try
  {
   CopyFile(sSourceFileName, sTargetFileName, I_FILE_OVERRIDE_ALWAYS);
   DeleteFile(sSourceFileName);
   bResult = true;
  } catch (IOException e)
  {
   e.printStackTrace();
  }
  return bResult;
 }

 public boolean FileExists(String sFileName)
 {
  File oFile = new File(sFileName);
  return oFile.exists();
 }

 public long GetFileHashValue(String sFileName)
 {
  int i = 0;
  int[] iHashArray = new int[SecureRandom.I_DOUBLELONG_BYTE_LENGTH];
  int iGlue = 0xA5;
  long iResult = 0;
  File oFile = null;
  FileInputStream oInput = null;
  byte[] iBuffer = new byte[1024];
  iGlue = SecureHash.Digest(null, iHashArray, iGlue, true);
  if (IsValuable(sFileName))
  {
   oFile = new File(sFileName);
  }
  try
  {
   oInput = new FileInputStream(oFile);
   for (i = 1024; i >= 1024;)
   {
    i = oInput.read(iBuffer);
    if (i > 0)
    {
     for (; i < 1024; ++i)
     {
      iBuffer[i] = (byte) 0;
     }
     iGlue = SecureHash.Digest(iBuffer, iHashArray, iGlue, false);
    }
   }
   oInput.close();
  } catch (Exception e)
  {
  }
  for (i = 0; i < SecureRandom.I_LONG_BYTE_LENGTH; ++i)
  {
   iResult = (long) ((iResult << 8) | (iHashArray[i] ^ iHashArray[SecureRandom.I_LONG_BYTE_LENGTH
     + i]));
  }
  return iResult;
 }

 public boolean WriteTextToFile(String sFileName, String sText, String sEncoding)
 {
  boolean bResult = true;
  File oFile = null;
  File oDir = null;
  String sDir = "";
  FileOutputStream oOutput = null;
  int i = 0;
  if (IsValuable(sFileName))
  {
   oFile = new File(sFileName);
   try
   {
    if (!oFile.exists())
    {
     sFileName = sFileName.replace('\\', '/');
     i = sFileName.lastIndexOf("/");
     if (i > 0)
     {
      sDir = sFileName.substring(0, i);
     }
     if (IsValuable(sDir))
     {
      oDir = new File(sDir);
      if (!oDir.exists())
      {
       oDir.mkdirs();
      }
     }
     oFile.createNewFile();
    } else
    {
     if (oFile.delete())
     {
      oFile.createNewFile();
     }
    }
   } catch (IOException e)
   {
    e.printStackTrace();
    bResult = false;
   }
  }
  if (bResult)
  {
   try
   {
    oOutput = new FileOutputStream(oFile);
   } catch (FileNotFoundException e)
   {
    e.printStackTrace();
    bResult = false;
   }
  }
  if (bResult)
  {
   try
   {
    byte[] oBytes = sText.getBytes(sEncoding);
    oOutput.write(oBytes, 0, oBytes.length);
   } catch (IOException e)
   {
    e.printStackTrace();
    bResult = false;
   }
  }
  if (bResult)
  {
   try
   {
    oOutput.close();
   } catch (IOException e)
   {
    e.printStackTrace();
    bResult = false;
   }
  }
  return bResult;
 };

 public boolean WriteTextToFile(String sFileName, String sText)
 {
  boolean bResult = true;
  File oFile = null;
  File oDir = null;
  String sDir = "";
  FileOutputStream oOutput = null;
  int i = 0;
  if (IsValuable(sFileName))
  {
   oFile = new File(sFileName);
   try
   {
    if (!oFile.exists())
    {
     sFileName = sFileName.replace('\\', '/');
     i = sFileName.lastIndexOf("/");
     if (i > 0)
     {
      sDir = sFileName.substring(0, i);
     }
     if (IsValuable(sDir))
     {
      oDir = new File(sDir);
      if (!oDir.exists())
      {
       oDir.mkdirs();
      }
     }
     oFile.createNewFile();
    } else
    {
     if (oFile.delete())
     {
      oFile.createNewFile();
     }
    }
   } catch (IOException e)
   {
    e.printStackTrace();
    bResult = false;
   }
  }
  if (bResult)
  {
   try
   {
    oOutput = new FileOutputStream(oFile);
   } catch (FileNotFoundException e)
   {
    e.printStackTrace();
    bResult = false;
   }
  }
  if (bResult)
  {
   try
   {
    oOutput.write(sText.getBytes(), 0, sText.length());
   } catch (IOException e)
   {
    e.printStackTrace();
    bResult = false;
   }
  }
  if (bResult)
  {
   try
   {
    oOutput.close();
   } catch (IOException e)
   {
    e.printStackTrace();
    bResult = false;
   }
  }
  return bResult;
 };

 public String ReadTextFromFile(String sFileName)
 {
  StringBuffer sResult = new StringBuffer("");
  File oFile = null;
  FileInputStream oInput = null;
  int i = 0;
  byte[] iBuffer = new byte[1024];
  if (IsValuable(sFileName))
  {
   oFile = new File(sFileName);
  }
  try
  {
   oInput = new FileInputStream(oFile);
   for (i = 1024; i >= 1024;)
   {
    i = oInput.read(iBuffer);
    if (i > 0)
    {
     sResult.append((new String(iBuffer, 0, i)));
    }
   }
   oInput.close();
  } catch (Exception e)
  {
   return "";
  }
  return sResult.toString();
 }

 public String ReadTextFromFile(String sFileName, String sEncoding)
 {
  StringBuffer sResult = new StringBuffer("");
  File oFile = null;
  if (IsValuable(sFileName))
  {
   oFile = new File(sFileName);
  }

  try
  {

   BufferedReader oBufferedReader = new BufferedReader(new InputStreamReader(
     new FileInputStream(oFile), sEncoding));

   while (oBufferedReader.ready())
   {
    sResult.append(oBufferedReader.readLine() + "\r\n");
   }

  } catch (UnsupportedEncodingException ue)
  {

   System.out.println("Not supported : ");

  } catch (IOException e)
  {

   System.out.println(e.getMessage());

  }
  return sResult.toString();
 }

 public String ReadUnicodeTextFromFile(String sFileName)
 {
  StringBuffer sResult = new StringBuffer("");
  BufferedReader bufferedReader = null;
  UnicodeReader unicodeReader = null;
  int i = 0;
  char[] iBuffer = new char[1024];
  File oFile = null;
  if (IsValuable(sFileName))
  {
   oFile = new File(sFileName);
   try
   {
    unicodeReader = new UnicodeReader(new FileInputStream(oFile), null);
    bufferedReader = new BufferedReader(unicodeReader);

    i = 1024;
    while (i >= 1024) // as long there are more than 1024 chars to
    // read - read
    // the next (maximum) 1024
    // chars block and add it to the result
    {
     i = bufferedReader.read(iBuffer);
     if (i > 0)
     {
      sResult.append((new String(iBuffer, 0, i)));
     }
    }

    bufferedReader.close();
   } catch (Exception e)
   {
    return ReadTextFromFile(sFileName);
   }
  }
  return sResult.toString();
 }

 public void CopyFile(String source_name, String dest_name, int iOverride)
   throws IOException
 {
  iOverride = Limited(iOverride, I_FILE_OVERRIDE_ALWAYS, I_FILE_OVERRIDE_NEWER);
  File SourceFile = new File(source_name);
  File DestinationFile = new File(dest_name);
  FileInputStream Source = null;
  FileOutputStream Destination = null;
  byte[] iBuffer;
  int iBytesRead;
  boolean bToCopy = true;
  try
  {
   if (!SourceFile.exists() || !SourceFile.isFile())
    throw new FileCopyException("FileCopy: no such source file: " + source_name);
   if (!SourceFile.canRead())
    throw new FileCopyException("FileCopy: source file " + "is unreadable: "
      + source_name);
   if (DestinationFile.exists())
   {
    if (DestinationFile.isFile())
    {
     if (iOverride == I_FILE_OVERRIDE_NEVER)
     {
      bToCopy = false;
     } else
     {
      if (!DestinationFile.canWrite())
       throw new FileCopyException("FileCopy: destination "
         + "file is unwriteable: " + dest_name);
     }
    } else
     throw new FileCopyException("FileCopy: destination " + "is not a file: "
       + dest_name);
   } else
   {
    File parentdir = FileGetParent(DestinationFile);
    if (!parentdir.exists())
    {
     parentdir.mkdirs();
    }
    if (!parentdir.exists())
     throw new FileCopyException("FileCopy: destination "
       + "directory doesn't exist: " + dest_name);
    if (!parentdir.canWrite())
     throw new FileCopyException("FileCopy: destination "
       + "directory is unwriteable: " + dest_name);
   }
   if (bToCopy)
   {
    if (!(((iOverride == I_FILE_OVERRIDE_DIFFERENT) && (SourceFile
      .lastModified() == DestinationFile.lastModified())) || ((iOverride == I_FILE_OVERRIDE_NEWER) && (SourceFile
      .lastModified() <= DestinationFile.lastModified()))))
    {
     Source = new FileInputStream(SourceFile);
     Destination = new FileOutputStream(DestinationFile);
     iBuffer = new byte[1024];
     Println(dest_name + " <- " + source_name);
     while (bToCopy)
     {
      iBytesRead = Source.read(iBuffer);
      if (iBytesRead == -1)
      {
       bToCopy = false;
      } else
      {
       Destination.write(iBuffer, 0, iBytesRead);
      }
     }
    }
   }
  } finally
  {
   if (Source != null)
   {
    try
    {
     Source.close();
    } catch (IOException e)
    {
     ;
    }
   }
   if (Destination != null)
   {
    try
    {
     Destination.close();
     DestinationFile.setLastModified(SourceFile.lastModified());
    } catch (IOException e)
    {
    }
   }
  }
 }

 public boolean CopyDirFiles(String sSourceDir, String sTargetDir, int iOverride)
 {
  return CopyDirFiles(sSourceDir, sTargetDir, "*.*", "", iOverride);
 }

 public boolean CopyDirFiles(String sSourceDir, String sTargetDir,
   String sPattern, int iOverride)
 {
  return CopyDirFiles(sSourceDir, sTargetDir, sPattern, "", iOverride);
 };

 public boolean CopyDirFiles(String sSourceDir, String sTargetDir,
   String sPattern, String sExclusionPattern, int iOverride)
 {
  boolean bResult = true;
  String[] sFiles = DirFilesList(sSourceDir, "", sPattern, sExclusionPattern);
  int i = 0;
  for (i = 0; i < sFiles.length; ++i)
  {
   try
   {
    CopyFile(sSourceDir + sFiles[i], sTargetDir + sFiles[i], iOverride);
   } catch (IOException e)
   {
    bResult = false;
    Println(e.getMessage());
   }
  }
  return bResult;
 };

 public String[] DirFilesList(String sSourceDir, String sSubDir)
 {
  return DirFilesList(sSourceDir, sSubDir, "*.*", "");
 };

 public String[] DirFilesList(String sSourceDir, String sSubDir, String sPattern)
 {
  return DirFilesList(sSourceDir, sSubDir, sPattern, "");
 };

 public String[] DirFilesList(String sSourceDir, String sSubDir,
   String sPattern, String sExclusionPattern)
 {
  File oSourceDir = new File(sSourceDir);
  String[] sFiles = oSourceDir.list();
  CStringArray sCollection = new CStringArray();
  int i = 0;
  if (oSourceDir.isDirectory())
  {
   for (i = 0; i < sFiles.length; ++i)
   {
    oSourceDir = new File(sSourceDir + "/" + sFiles[i]);
    if (oSourceDir.isDirectory())
    {
     sCollection.Append(DirFilesList(sSourceDir + "/" + sFiles[i], sSubDir
       + "/" + sFiles[i], sPattern, sExclusionPattern));
    } else
    {
     if (oMatcher.MatchesPattern(sSubDir + "/" + sFiles[i], sPattern))
     {
      if (!oMatcher
        .MatchesPattern(sSubDir + "/" + sFiles[i], sExclusionPattern))
      {
       sCollection.Append(sSubDir + "/" + sFiles[i]);
      }
     }
    }
   }
   ;
  }
  ;
  return sCollection.ToArray();
 };

 public ArrayList DirFilesListAsFile(String sSourceDir, String sSubDir,
   String sPattern, String sExclusionPattern, int sortDirection)
 {
  CDateSortedFile oCurrentFile = new CDateSortedFile(sSourceDir, sortDirection);
  String[] sFiles = oCurrentFile.list();
  ArrayList fileList = new ArrayList();
  int i = 0;
  if (oCurrentFile.isDirectory())
  {
   for (i = 0; i < sFiles.length; ++i)
   {
    oCurrentFile = new CDateSortedFile(sSourceDir + "/" + sFiles[i],
      sortDirection);
    if (oCurrentFile.isDirectory())
    {
     fileList.addAll(DirFilesListAsFile(sSourceDir + "/" + sFiles[i], sSubDir
       + "/" + sFiles[i], sPattern, sExclusionPattern, sortDirection));
    } else
    {
     if (oMatcher.MatchesPattern(sSubDir + "/" + sFiles[i], sPattern))
     {
      if (!oMatcher
        .MatchesPattern(sSubDir + "/" + sFiles[i], sExclusionPattern))
      {
       CDateSortedFile f = new CDateSortedFile(sSourceDir + "/" + sFiles[i],
         sortDirection);
       if (f.exists())
       {
        fileList.add(f);
       }
      }
     }
    }
   }
   ;
  }
  ;
  if (sortDirection != CDateSortedFile.SORTED_LIST_FILE_NONE)
  {
   Collections.sort(fileList);
  }
  return fileList;
 };

 // Private
 private File FileGetParent(File f)
 {
  String dirname = f.getParent();
  if (dirname == null)
  {
   if (f.isAbsolute())
    return new File(File.separator);
   else
    return new File(System.getProperty("user.dir"));
  }
  return new File(dirname);
 }

 public String GetParentPath(String sFilePath)
 {
  int lastSeperatorLocation = sFilePath.lastIndexOf(File.separator);
  if (lastSeperatorLocation > 0)
  {
   return sFilePath.substring(0, lastSeperatorLocation);
  }
  return null;
 }
}

class FileCopyException extends IOException
{
 private static final long serialVersionUID = 830726483064803706L;

 public FileCopyException(String msg)
 {
  super(msg);
 }
}
// Trash Bin
/*
 * 
 */